#ifndef XRPL_PEERFINDER_STORESQDB_H_INCLUDED
#define XRPL_PEERFINDER_STORESQDB_H_INCLUDED

#include <xrpld/app/rdb/PeerFinder.h>
#include <xrpld/core/SociDB.h>
#include <xrpld/peerfinder/detail/Store.h>

namespace ripple {
namespace PeerFinder {

/** Database persistence for PeerFinder using SQLite */
class StoreSqdb : public Store
{
private:
    beast::Journal m_journal;
    soci::session m_sqlDb;

public:
    enum {
        // This determines the on-database format of the data
        currentSchemaVersion = 4
    };

    explicit StoreSqdb(
        beast::Journal journal = beast::Journal{beast::Journal::getNullSink()})
        : m_journal(journal)
    {
    }

    ~StoreSqdb()
    {
    }

    void
    open(BasicConfig const& config)
    {
        init(config);
        update();
    }

    // Loads the bootstrap cache, calling the callback for each entry
    //
    std::size_t
    load(load_callback const& cb) override
    {
        std::size_t n(0);

        readPeerFinderDB(m_sqlDb, [&](std::string const& s, int valence) {
            beast::IP::Endpoint const endpoint(
                beast::IP::Endpoint::from_string(s));

            if (!is_unspecified(endpoint))
            {
                cb(endpoint, valence);
                ++n;
            }
            else
            {
                JLOG(m_journal.error())
                    << "Bad address string '" << s << "' in Bootcache table";
            }
        });

        return n;
    }

    // Overwrites the stored bootstrap cache with the specified array.
    //
    void
    save(std::vector<Entry> const& v) override
    {
        savePeerFinderDB(m_sqlDb, v);
    }

    // Convert any existing entries from an older schema to the
    // current one, if appropriate.
    void
    update()
    {
        updatePeerFinderDB(m_sqlDb, currentSchemaVersion, m_journal);
    }

private:
    void
    init(BasicConfig const& config)
    {
        initPeerFinderDB(m_sqlDb, config, m_journal);
    }
};

}  // namespace PeerFinder
}  // namespace ripple

#endif
